package kr.as3.component.ui
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	[Event ( name="dragMargin", type="kr.as3.component.ui.DragFrameEvent" ) ]

	public class DragFrame extends Sprite
	{
		// things on stage.
		public var border: Sprite;
		public var actual: Sprite;
		
		private var rectBorder: Rectangle;
		private var rectActual: Rectangle;
		
		public function DragFrame()
		{
			this.border.buttonMode = true;
			this.border.addEventListener( MouseEvent.MOUSE_DOWN, dragStart );
			
			this.rectBorder = this.border.getBounds( this );
			this.rectActual = this.actual.getBounds( this );
			
			trace( this.rectBorder );
			trace( this.rectActual );
		}
		
		private var rect: Rectangle;
		public function setDragArea( $rect: Rectangle ): void
		{
			this.rect = $rect.clone();
		}
		
		private var startPoint: Point;
		private function dragStart( e: MouseEvent ): void
		{
			this.stage.addEventListener( MouseEvent.MOUSE_UP, dragStop );
			this.stage.addEventListener( Event.MOUSE_LEAVE, dragStop );
			
			this.addEventListener( Event.ENTER_FRAME, dragListener );
			
			if( this.startPoint == null )
				this.startPoint = new Point();
			
			this.startPoint.x = this.stage.mouseX - this.x;
			this.startPoint.y = this.stage.mouseY - this.y;
		}
		
		private function dragListener( e: Event ): void
		{
			this.x = this.stage.mouseX - this.startPoint.x;
			this.y = this.stage.mouseY - this.startPoint.y;
			
			if( this.rect == null )
				return;
			
			checkX:
			{
				if( this.x < this.rect.x )
				{
					this.x = this.rect.x;
					break checkX;
				}
				
				if( this.x + this.width > this.rect.x + this.rect.width )
				{
					this.x = this.rect.x + this.rect.width - this.width;
					break checkX;
				}
			}
			
			checkY:
			{
				if( this.y < this.rect.y )
				{
					this.y = this.rect.y;
					break checkY;
				}
				
				if( this.y + this.height > this.rect.y + this.rect.height )
				{
					this.y = this.rect.y + this.rect.height - this.height;
					break checkY;
				}
			}
			
			var marginPoint: Point = new Point();
			marginPoint.x = this.x - ( this.stage.mouseX - this.startPoint.x );
			marginPoint.y = this.y - ( this.stage.mouseY - this.startPoint.y );
			
			checkMarginX:
			{
				if( marginPoint.x > this.rectActual.x - this.rectBorder.x )
				{
					marginPoint.x = this.rectActual.x - this.rectBorder.x
					break checkMarginX;
				}
				
				if( marginPoint.x < ( this.rectActual.x + this.rectActual.width ) - ( this.rectBorder.x + this.rectBorder.width ) )
				{
					marginPoint.x = ( this.rectActual.x + this.rectActual.width ) - ( this.rectBorder.x + this.rectBorder.width );
					break checkMarginX;
				}
			}
			
			checkMarginY:
			{
				if( marginPoint.y > this.rectActual.y - this.rectBorder.y )
				{
					marginPoint.y = this.rectActual.y - this.rectBorder.y
					break checkMarginY;
				}
				
				if( marginPoint.y < ( this.rectActual.y + this.rectActual.height ) - ( this.rectBorder.y + this.rectBorder.height ) )
				{
					marginPoint.y = ( this.rectActual.y + this.rectActual.height ) - ( this.rectBorder.y + this.rectBorder.height );
					break checkMarginY;
				}
			}
			
			this.dispatchEvent( new DragFrameEvent( DragFrameEvent.DRAG_MARGIN, marginPoint ) );
		}
		
		private function dragStop( e: Event ): void
		{
			this.removeEventListener( Event.ENTER_FRAME, dragListener );
			
			this.stage.removeEventListener( Event.MOUSE_LEAVE, dragStop );
			this.stage.removeEventListener( MouseEvent.MOUSE_UP, dragStop );
		}
	}
}